<!--
    添加编辑权限核心组件

    参数：
        id：数据id，（添加模式为空，重命名模式请传值）
        enabledSubmitButtonGroup：是否显示提交按钮组（默认不显示），一般用于单独引用此组件在时候显示提交按钮组

    事件：
        saveDataSuccess：点击按钮并成功保存后触发

    导出：
        stateIsSavingData：属性-是否正在保存数据
        handleAddOrEditData：函数-提交表单数据
        handleResetData：函数-重置表单数据
        handleCheckSafetyClose：函数-检查是否可以关闭对话框
-->
<template>
  <div v-loading="(stateIsLoadingData || stateIsSavingData) && { text: stateProgress }">
    <el-form ref="refForm" :model="modelFormData" :rules="modelFormRules" label-width="auto" @submit.prevent>
      <el-form-item label="权限名称" prop="name">
        <el-input v-model="modelFormData.name" placeholder="请输入权限名称" clearable maxlength="256" show-word-limit />
      </el-form-item>
      <el-form-item label="权限代码" prop="value">
        <el-input
          v-model="modelFormData.value"
          placeholder="请输入权限代码"
          show-word-limit
          maxlength="256"
          clearable
        />
      </el-form-item>
      <el-form-item label="业务类型" prop="business">
        <el-input
          v-model="modelFormData.business"
          placeholder="请输入业务类型"
          show-word-limit
          maxlength="256"
          clearable
        />
      </el-form-item>
      <el-form-item label="排序码" prop="sortCode">
        <el-input-number style="width: 100%" v-model="modelFormData.sortCode" />
      </el-form-item>
      <el-form-item label="描述" prop="description">
        <!-- 这里一定要加overflow: hidden，防止其与外部滚动条冲突 -->
        <el-input
          :autosize="{ minRows: 2, maxRows: 5 }"
          v-model="modelFormData.description"
          style="overflow: hidden"
          placeholder="描述"
          show-word-limit
          type="textarea"
          maxlength="521"
        />
      </el-form-item>
    </el-form>

    <el-row justify="end" style="margin-top: 20px" v-if="props.enableSubmitButtonGroup">
      <el-button
        v-if="!modelFormData.id"
        type="primary"
        :icon="Select"
        :loading="stateIsSavingData"
        @click="handleAddOrEditData"
      >
        保存
      </el-button>
      <el-button v-else type="success" :icon="Edit" :loading="stateIsSavingData" @click="handleAddOrEditData">
        保存更改
      </el-button>
      <el-button :icon="Refresh" :loading="stateIsSavingData" @click="handleResetData" title="恢复到默认值">
        重置
      </el-button>
    </el-row>
  </div>
</template>

<script setup lang="ts">
  import { Edit, Refresh, Select } from '@element-plus/icons-vue'
  import { ElMessage, FormInstance, FormRules } from 'element-plus'
  import { onMounted, reactive, ref } from 'vue'
  import { SysPermissionApi } from '/@/api/sysApi/SysPermissionApi.ts'
  import PermissionType = SysPermissionApi.PermissionType

  const props = withDefaults(
    defineProps<{
      id?: number // 对象id，为空时为新增，非空时为编辑
      enableSubmitButtonGroup: boolean // 是否显示提交按钮组
    }>(),
    { enableSubmitButtonGroup: false }
  )

  // 表单默认值
  const getDefaultModelFormData = (): PermissionType => {
    return { sortCode: 1 }
  }

  const refForm = ref<FormInstance>() // 表单对象

  const modelFormData = ref<PermissionType>(getDefaultModelFormData()) // 表单数据
  const modelFormRules = reactive<FormRules<PermissionType>>({
    name: [{ required: true, message: '权限名称不能为空', trigger: 'blur' }],
    value: [{ required: true, message: '权限值不能为空', trigger: 'blur' }],
  })

  const stateIsSavingData = ref<boolean>(false) // 是否正在保存数据
  const stateIsLoadingData = ref<boolean>(false) // 是否正在加载页面
  const stateProgress = ref<string>(' ') // 请求发送进度，此处必须是空格字符，否则进度条无法显示

  const emits = defineEmits<{ (e: 'saveDataSuccess'): void }>()

  onMounted(() => {
    handleResetData() // 设置默认数据
  })

  /**
   * 获取详情
   */
  const getData = async (id: number) => {
    stateIsLoadingData.value = true
    try {
      const { data } = await SysPermissionApi.detail(id)
      modelFormData.value = data.data
    } finally {
      stateIsLoadingData.value = false
    }
  }

  const handleAddOrEditData = () => {
    refForm.value?.validate(async (valid, fields) => {
      if (valid) {
        stateIsSavingData.value = true
        try {
          if (props.id) {
            // 编辑模式
            await SysPermissionApi.edit(modelFormData.value)
            ElMessage.success('保存成功')
          } else {
            // 添加模式
            await SysPermissionApi.add(modelFormData.value)
            ElMessage.success('保存成功')
          }
          stateIsSavingData.value = false
          emits('saveDataSuccess')
        } catch {
          stateIsSavingData.value = false
        }
      } else {
        console.warn('表单校验失败', fields)
      }
    })
  }

  /**
   * 根据添加或编辑模式，重新设置表单数据
   */
  const handleResetData = async () => {
    modelFormData.value = getDefaultModelFormData()
    if (props.id) {
      await getData(props.id)
    }
  }

  /**
   * 是否可以安全关闭
   */
  const handleCheckSafetyClose = async () => {
    return true
  }

  // 导出的对象，可以让上级组件访问到。必须放到导出的对象下面，否则导致对象未声明
  defineExpose({ stateIsSavingData, handleAddOrEditData, handleResetData, handleCheckSafetyClose })
</script>

<style lang="scss" scoped></style>